<template>
    <div>
        <div class="i-layout-page-header">
            <PageHeader title="菜单资源" content="" hidden-breadcrumb/>
        </div>
        <Row :gutter="24" class="ivu-mt">
            <Col :xl="10" :lg="24" :md="24" :sm="24" :xs="24" class="ivu-mb">
                <Affix :offset-top="108">
                    <Card :bordered="true" dis-hover class="ivu-mb">
                        <div slot="title">
                            <Dropdown>
                                <Button type="primary" ghost>
                                    添加菜单
                                    <Icon type="ios-arrow-down"></Icon>
                                </Button>
                                <DropdownMenu slot="list">
                                    <DropdownItem @click.native="handleOpenCreateHeader">添加顶级菜单</DropdownItem>
                                    <DropdownItem :disabled="!menuInfo" @click.native="handleOpenCreateSider">添加子菜单
                                    </DropdownItem>
                                </DropdownMenu>
                            </Dropdown>
                            <Button type="primary" ghost class="ivu-ml" v-show="!toggleExpand"
                                    @click="handleToggleExpandAll(true)">
                                <Icon type="md-list"/>
                                全部展开
                            </Button>
                            <Button type="primary" ghost class="ivu-ml" v-show="toggleExpand"
                                    @click="handleToggleExpandAll(false)">
                                <Icon type="md-list"/>
                                全部收起
                            </Button>
                            <Button type="error" ghost class="ivu-ml" v-show="selectedData.length"
                                    @click="handleDeleteMultiple">
                                <Icon type="md-trash"/>
                                批量删除
                            </Button>
                        </div>
                        <div :style="menuListStyle">
                            <div class="ivu-p-8">
                                <Input v-if="menuList.length || query !== ''" v-model="query" search
                                       placeholder="输入菜单名称搜索" @on-change="handleSearch"/>
                            </div>
                            <Tree
                                :data="menuList"
                                show-checkbox
                                check-strictly
                                @on-select-change="handleSelectNode"
                                @on-check-change="handleCheckNode"
                                @on-contextmenu="handleContextMenu">
                                <template slot="contextMenu">
                                    <DropdownItem @click.native="handleContextMenuEdit">编辑</DropdownItem>
                                    <DropdownItem @click.native="handleContextMenuNew">添加子菜单</DropdownItem>
                                    <DropdownItem divided @click.native="handleContextMenuDelete"
                                                  style="color: #ed4014">删除
                                    </DropdownItem>
                                </template>
                            </Tree>
                        </div>
                    </Card>
                </Affix>
            </Col>
            <Col :xl="14" :lg="24" :md="24" :sm="24" :xs="24" class="ivu-mb">
                <Card :bordered="true" dis-hover class="ivu-mb">
                    <div slot="title">
                        <Avatar icon="md-apps" size="small" v-color="'#1890ff'" v-bg-color="'#e6f7ff'"/>
                        <span class="ivu-pl-8">编辑菜单</span>
                        <span v-if="menuInfo">：{{ menuInfo.title }}</span>
                    </div>
                    <div>
                        <div v-show="!menuInfo">
                            <Alert>从菜单列表选择一项后，进行编辑</Alert>
                        </div>
                        <Form
                            v-if="editMenuData && editMenuReady"
                            ref="infoForm"
                            :model="editMenuData"
                            :rules="editMenuRules"
                            label-position="right"
                            :label-width="100"
                            label-colon
                            hide-required-mark>
                            <!--              <FormItem label="类型">-->
                            <!--                <span v-if="editMenuData.name">顶栏菜单</span>-->
                            <!--                <span v-else>侧边栏菜单</span>-->
                            <!--              </FormItem>-->
                            <FormItem prop="title" label="标题">
                                <Input v-model="editMenuData.title" placeholder="请输入标题，必填"/>
                            </FormItem>
<!--                            <FormItem prop="subtitle" label="副标题" v-if="false">-->
<!--                                <Input v-model="editMenuData.subtitle" placeholder="请输入副标题"/>-->
<!--                            </FormItem>-->
                            <FormItem prop="menuNum" label="菜单序号">
                                <Input v-model="editMenuData.menuNum" placeholder="请输入菜单序号"/>
                            </FormItem>
                            <FormItem prop="menuPath" label="路径">
                                <Input v-model="editMenuData.menuPath" placeholder="请输入路径,必填"/>
                            </FormItem>
<!--                            <FormItem prop="path" label="文件名">-->
<!--                                <Input v-model="editMenuData.path" placeholder="请输入文件名，必填"/>-->
<!--                            </FormItem>-->
                            <FormItem prop="icon" label="图标">
                                <Input v-model="editMenuData.icon" placeholder="请输入图标"/>
                            </FormItem>
<!--                            <FormItem prop="systemId" label="所属系统">-->
<!--                                <Select v-model="editMenuData.systemId" transfer placeholder="请选择">-->
<!--                                    <Option v-for="item in bizSysData" :value="item.id" :key="item.id">{{-->
<!--                                            item.sysName-->
<!--                                        }}-->
<!--                                    </Option>-->
<!--                                </Select>-->
<!--                            </FormItem>-->
                            <FormItem>
                                <Button type="primary" @click="handleSubmitUpdate" :loading="submitting">保存修改</Button>
                                <Button @click="handleResetUpdate" class="ivu-ml">重置</Button>
                            </FormItem>
                        </Form>
                    </div>
                </Card>
            </Col>
        </Row>
        <Drawer
            :styles="drawer.styles"
            v-model="drawer.show"
            :before-close="handleCloseEdit"
            :transfer="false"
            width="360">
            <div slot="header" class="ivu-drawer-header-inner">
                <template v-if="drawer.type === 'header'">添加顶级菜单</template>
                <template v-if="drawer.type === 'sider'">
                    添加子菜单：<span v-if="menuInfo">{{ menuInfo.title }}</span>
                </template>
            </div>
            <Form
                v-if="menuData"
                ref="menuForm"
                :model="menuData"
                :rules="drawer.type === 'header' ? headerMenuRules : siderMenuRules"
                label-position="right"
                :label-width="100"
                label-colon
                hide-required-mark>
                <FormItem prop="title" label="标题">
                    <Input v-model="menuData.title" placeholder="请输入标题，必填"/>
                </FormItem>
<!--                <FormItem prop="subtitle" label="副标题" v-if="drawer.type === 'sider'">-->
<!--                    <Input v-model="menuData.subtitle" placeholder="请输入副标题"/>-->
<!--                </FormItem>-->
                <FormItem prop="menuNum" label="菜单序号">
                    <Input v-model="menuData.menuNum" placeholder="请输入菜单序号"/>
                </FormItem>
                <FormItem prop="menuPath" label="路径">
                    <Input v-model="menuData.menuPath" placeholder="请输入路径,必填"/>
                </FormItem>
<!--                <FormItem prop="path" label="文件名">-->
<!--                    <Input v-model="menuData.path" placeholder="请输入文件名，必填"/>-->
<!--                </FormItem>-->
                <FormItem prop="icon" label="图标">
                    <Input v-model="menuData.icon" placeholder="请输入图标"/>
                </FormItem>
<!--                <FormItem prop="systemId" label="所属系统">-->
<!--                    <Select v-model="menuData.systemId">-->
<!--                        <Option v-for="item in bizSysData" :value="item.id" :key="item.id">{{ item.sysName }}</Option>-->
<!--                    </Select>-->
<!--                </FormItem>-->
            </Form>
            <div class="page-sys-menu-drawer-footer" v-if="drawer.type === 'header'">
                <Button type="primary" @click="handleSubmitHeader" :loading="submitting">提交</Button>
            </div>
            <div class="page-sys-menu-drawer-footer" v-if="drawer.type === 'sider'">
                <Button type="primary" @click="handleSubmitSider" :loading="submitting">提交</Button>
            </div>
        </Drawer>
    </div>
</template>
<script>
import {cloneDeep} from 'lodash';
import {mapState} from "vuex";
import system from "public/service/scenario/system";
const headerMenu = {
    id: '',
    title: '',
    path: '',
    name: '',
    icon: '',
    hideSider: false,
    target: '_self',
    systemId: '',
    menuNum: '',
    menuPath: '',
};
const siderMenu = {
    id: '',
    title: '',
    subtitle: '',
    path: '',
    icon: '',
    target: '_self',
    divided: false,
    header: '',
    systemId: '',
    menuNum: '',
    menuPath: ''
};
export default {
    name: 'system-menu',
    data() {
        return {
            loading: false,
            sourceMenuList: [],
            menuList: [],
            selectedData: [],
            toggleExpand: true,
            menuInfo: null,
            contextMenuInfo: null,
            query: '',
            drawer: {
                show: false,
                type: 'header', // header || sider
                styles: {
                    height: 'calc(100% - 55px)',
                    overflow: 'auto',
                    paddingBottom: '53px',
                    position: 'static'
                }
            },
            submitting: false,
            menuData: null,
            menuDataString: '',
            headerMenuRules: {
                title: [
                    {required: true, message: '请输入标题', trigger: 'blur'}
                ],
                menuPath: [
                    {required: true, message: '请输入菜单路径', trigger: 'blur'}
                ],
                // path: [
                //     {required: true, message: '请输入文件名', trigger: 'blur'}
                // ],
                // systemId: [
                //     {required: true, type: 'string', message: '请选择所属系统', trigger: 'change'}
                // ]
            },
            siderMenuRules: {
                title: [
                    {required: true, message: '请输入标题', trigger: 'blur'}
                ],
                menuPath: [
                    {required: true, message: '请输入菜单路径', trigger: 'blur'}
                ],
                // path: [
                //     {required: true, message: '请输入文件名', trigger: 'blur'}
                // ],
                // systemId: [
                //     {required: true, type: 'string', message: '请选择所属系统', trigger: 'change'}
                // ]
            },
            editMenuRules: {
                title: [
                    {required: true, message: '请输入标题', trigger: 'blur'}
                ],
                menuPath: [
                    {required: true, message: '请输入菜单路径', trigger: 'blur'}
                ],
                // path: [
                //     {required: true, message: '请输入文件名', trigger: 'blur'}
                // ],
                // systemId: [
                //     {required: true, type: 'string', message: '请选择所属系统', trigger: 'change'}
                // ]
            },
            editMenuData: null,
            editMenuReady: true,
            menuCond: {
                condition: {
                    className: 'Menu',
                    value: {}
                }
            },
            //数据库获取的菜单数据列表
            menuDataList: [],
            bizSysCond: {
                condition: {
                    className: 'BizSys',
                    value: {}
                }
            },
            bizSysData: [],
            menuObject:null,
        }
    },
    computed: {
        ...mapState('admin/api', [
            'api'
        ]),
        menuListStyle() {
            return {
                height: document.body.clientHeight - 330 + 'px',
                overflow: 'auto'
            }
        },
        lang () {
            return {
                'en-US': {
                    cancel: 'cancel',
                    confirmDelete: 'confirm delete?'
                },
                'zh-CN': {
                    cancel: '取消',
                    confirmDelete: '确认删除？'
                }
            }[this.G_Locale]
        },
    },
    methods: {
        // 获取菜单数据
        handleGetMenuList() {
            this.getMenuList();
        },
        //通过服务端请求获取菜单列表
        getMenuList() {
            this.loading = true;
            let condition = "";
            if (this.query != null && this.query != "") {
                condition="menuName like '%"+this.query+"%'";
            }
            this.$api.Menu.query({condition}).then(records => {
                this.menuDataList = [];
                this.sourceMenuList =[];
                if(records && records.length > 0){
                  records.forEach(item=>{
                    let tempMenuData = {
                      id: item.id,
                      createTime: item.createTime,
                      updateTime: item.updateTime,
                      title: item.menuName,
                      subtitle: item.menuTitle,
                      path: item.menuUrl,
                      icon: item.showPic,
                      target: item.targetArea,
                      divided: false,
                      name: item.fatherMenuId == "" ? item.menuName : "",
                      header: item.fatherMenuId,
                      fatherMenuId: item.fatherMenuId,
                      systemId: item.sysId,
                      menuNum: item.menuNum,
                      menuPath: item.menuPath,
                    };
                    this.menuDataList.push(tempMenuData);
                  })
                  this.buildMenuDataList();
                  this.sourceMenuList = this.menuList;
                  this.handleToggleExpandAll(true);
                }else {
                  this.menuDataList = [];
                }
                this.loading = false;
            }).finally(()=>{
                this.loading = false;
            })
        },
        //构建菜单数据列表
        buildMenuDataList() {
            this.menuDataList.sort((a, b) => a.menuNum - b.menuNum);
            let topMenuList = this.menuDataList.filter(item => item.fatherMenuId == "" || item.fatherMenuId == null);
            if (topMenuList != null && topMenuList.length > 0) {
                topMenuList.forEach(menu => {
                    this.buildChildrenMenuList(menu);
                })
            }
            this.menuList = cloneDeep(topMenuList);
        },
        //构建子菜单列表
        buildChildrenMenuList(topMenu) {
            let childrenMenuList = this.menuDataList.filter(item => item.fatherMenuId == topMenu.id);
            if (childrenMenuList != null && childrenMenuList.length > 0) {
                topMenu.children = childrenMenuList;
                topMenu.children.forEach(menu => {
                    this.buildChildrenMenuList(menu);
                })
            }
        },
        // 清空所有已选项
        handleClearSelect() {
            this.selectedData = [];
        },
        // 展开所有树
        handleToggleExpandAll(status) {
            this.toggleExpand = status;
            this.menuList = this.handleToggleExpandNode(this.menuList, status, []);
        },
        /**
         * @description 递归状态
         * @param {Array} menuList 原数据
         * @param {Boolean} isExpand 是否展开
         * @param {Array} lastList 递归数据
         * */
        handleToggleExpandNode(menuList, isExpand, lastList) {
            menuList.forEach(menu => {
                let newMenu = {};
                for (let i in menu) {
                    if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                }
                newMenu.expand = isExpand;
                newMenu.contextmenu = true;
                if (menu.children && menu.children.length) newMenu.children = [];
                lastList.push(newMenu);
                menu.children && this.handleToggleExpandNode(menu.children, isExpand, newMenu.children);
            });
            return lastList;
        },
        handleSelectNode(item) {
            this.menuInfo = item.length ? item[0] : null;
            this.handleInitEditMenuData();
        },
        handleCheckNode(items) {
            this.selectedData = items;
        },
        handleContextMenu(item) {
            this.contextMenuInfo = item;
        },
        handleContextMenuEdit() {
            this.menuInfo = this.contextMenuInfo;
            this.handleInitEditMenuData();
            this.menuList = this.handleSelectNodeById(this.menuList, this.menuInfo.id, []);
        },
        handleSelectNodeById(menuList, id, lastList) {
            menuList.forEach(menu => {
                let newMenu = {};
                for (let i in menu) {
                    if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                }

                newMenu.selected = newMenu.id === id;
                if (menu.children && menu.children.length) newMenu.children = [];

                lastList.push(newMenu);
                menu.children && this.handleSelectNodeById(menu.children, id, newMenu.children);
            });
            return lastList;
        },
        handleSearch() {
            const query = this.query;
            this.menuInfo = null;
            this.selectedData = [];
            this.contextMenuInfo = null;
            if (query) {
                this.menuList = this.handleQueryNode(this.sourceMenuList, query, []);
            } else {
                this.handleInitMenuList();
            }
        },
        handleInitMenuList() {
            this.menuList = cloneDeep(this.sourceMenuList);
            this.handleToggleExpandAll(true);
        },
        handleQueryNode(menuList, query, queryList) {
            menuList.forEach(menu => {
                let newMenu = {};
                for (let i in menu) {
                    if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                }
                if (newMenu.title.indexOf(query) > -1) queryList.push(newMenu);
                if (menu.children && menu.children.length) newMenu.children = [];
                menu.children && this.handleQueryNode(menu.children, query, queryList);
            });
            return queryList;
        },
        handleOpenCreateHeader() {
            this.menuData = cloneDeep(headerMenu);
            this.menuDataString = JSON.stringify(this.menuData);
            this.drawer.type = 'header';
            this.drawer.show = true;
        },
        handleOpenCreateSider() {
            if (!this.menuInfo) return;
            this.menuData = cloneDeep(siderMenu);
            this.menuData.header = this.menuInfo.header;
            this.menuDataString = JSON.stringify(this.menuData);
            this.drawer.type = 'sider';
            this.drawer.show = true;
        },
        handleContextMenuNew() {
            this.menuInfo = this.contextMenuInfo;
            this.handleInitEditMenuData();
            this.menuList = this.handleSelectNodeById(this.menuList, this.menuInfo.id, []);
            this.handleOpenCreateSider();
        },
        handleCloseEdit() {
            // 判断内容是否修改，没修改则直接关闭
            const editMenuData = cloneDeep(this.menuData);
            const editMenuDataString = JSON.stringify(editMenuData);
            if (editMenuDataString !== this.menuDataString) {
                return new Promise((resolve) => {
                    resolve();
                });
            } else {
                this.menuData = null;
            }
        },
        handleSubmitHeader() {
            this.$refs.menuForm.validate(valid => {
                if (valid) {
                    if (this.submitting) return;
                    this.submitting = true;
                    this.createHeaderMenu();
                }
            });
        },
        createHeaderMenu() {
            let menu = {
                menuName: this.menuData.title,
                menuTitle: this.menuData.subtitle,
                menuUrl: this.menuData.path,
                showPic: this.menuData.icon,
                menuNum: this.menuData.menuNum,
                menuPath: this.menuData.menuPath,
                targetArea: this.menuData.targetArea
            };
            this.$api.Menu.add(menu).then(res => {
                this.submitting = false;
                this.drawer.show = false;
                this.menuData = null;
                // 完成后刷新数据
                this.handleClearSelect();
                this.handleGetMenuList();
            })
        },
        handleSubmitSider() {
            this.$refs.menuForm.validate(valid => {
                if (valid) {
                    if (this.submitting) return;
                    this.submitting = true;
                    this.createSiderMenu();
                }
            });
        },

        createSiderMenu() {
            let menu = {
                menuName: this.menuData.title,
                menuTitle: this.menuData.subtitle,
                menuUrl: this.menuData.path,
                showPic: this.menuData.icon,
                menuNum: this.menuData.menuNum,
                menuPath: this.menuData.menuPath,
                fatherMenuId: this.menuInfo.id,
                sysId: this.menuData.sysId,
                targetArea: this.menuData.target
            };
            this.$api.Menu.add(menu).then(res => {
                this.submitting = false;
                this.drawer.show = false;
                this.menuData = null;
                this.handleClearSelect();
                this.handleGetMenuList();
            })
        },
        handleContextMenuDelete() {
            if (this.submitting) return;
            this.menuInfo = this.contextMenuInfo;
            this.handleInitEditMenuData();
            this.menuList = this.handleSelectNodeById(this.menuList, this.menuInfo.id, []);
            let _this = this;
            this.$Modal.confirm({
                title: this.lang['confirmDelete'],
                cancelText: this.lang['cancel'],
                content: `您确认要删除菜单<strong>${this.menuInfo.title}</strong>吗？`,
                onOk () {
                    _this.deleteMenu();
                }
            })
        },
        //删除菜单
        deleteMenu() {
            let menu = this.menuDataList.find(item=>item.fatherMenuId===this.menuInfo.id);
            if(menu){
                this.$Modal.remove();
                this.$Message.warning("请先删除子菜单");
                return;
            }

            this.$api.Menu.deleteById(this.menuInfo.id).then(res => {
                this.submitting = false;
                this.$Modal.remove();
                this.menuInfo = null;
                this.editMenuData = null;
                this.handleClearSelect();
                this.handleGetMenuList();
            })
        },

        handleDeleteMultiple() {
            if (this.submitting) return;
            const ids = this.selectedData.map(item => item.id);
            const titles = this.selectedData.map(item => item.title);
            let _this = this;
            this.$Modal.confirm({
                title: this.lang['confirmDelete'],
                cancelText: this.lang['cancel'],
                content: `您确认要删除菜单<strong>${titles}</strong>吗？`,
                onOk () {
                    _this.deleteMenuMultiple(ids);
                }
            })
        },

        deleteMenuMultiple(ids) {
            for (let i = 0; i < ids.length; i++) {
                let menu = this.menuDataList.find(item=>item.fatherMenuId===ids[i]);
                if(menu){
                    this.$Modal.remove();
                    this.$Message.warning("请先删除"+menu.title+"子菜单");
                    return;
                }
            }
            this.$api.Menu.deleteByIds(ids).then(res => {
                this.submitting = false;
                this.$Modal.remove();
                this.menuInfo = null;
                this.editMenuData = null;
                this.handleClearSelect();
                this.handleGetMenuList();
            });
        },
        handleInitEditMenuData() {
            let menuData = null;
            if (this.menuInfo) {
                if (this.menuInfo.name) {
                    menuData = cloneDeep(headerMenu);
                } else {
                    menuData = cloneDeep(siderMenu);
                }
                for (let i in menuData) {
                    if (i in this.menuInfo) menuData[i] = this.menuInfo[i];
                }
            }
            this.editMenuData = menuData;
            this.editMenuReady = false;
            this.$nextTick(() => {
                this.editMenuReady = true;
            });
        },
        // 修改菜单
        handleSubmitUpdate() {
            this.$refs.infoForm.validate(valid => {
                if (valid) {
                    if (this.submitting) return;
                    this.submitting = true;
                    this.updateMenu();
                }
            });
        },
        updateMenu() {
            let menu = {
                id: this.menuInfo.id,
                menuName: this.editMenuData.title,
                menuTitle: this.editMenuData.subtitle,
                menuUrl: this.editMenuData.path,
                showPic: this.editMenuData.icon,
                menuNum: this.editMenuData.menuNum,
                menuPath: this.editMenuData.menuPath,
                systemId: this.editMenuData.systemId,
                targetArea: this.editMenuData.target
            };
            this.$api.Menu.update(menu).then(res => {
                this.submitting = false;
                this.drawer.show = false;
                this.menuData = null;
                this.handleClearSelect();
                this.handleGetMenuList();
            })
        },
        handleResetUpdate() {
            this.$refs.infoForm.resetFields();
        },
    },
    mounted() {
        this.handleGetMenuList();
    }
}
</script>
<style lang="less">
.page-sys-menu {
    &-drawer {
        &-footer {
            width: 100%;
            position: absolute;
            bottom: 0;
            left: 0;
            border-top: 1px solid #e8e8e8;
            padding: 10px 16px;
            text-align: right;
            background: #fff;
        }
    }

    &-icon-select {
        .i-icon-select-transfer {
            width: 280px !important;
        }

        .i-icon-select-drop-main {
            width: 280px !important;
            height: 200px;
            overflow: auto;
        }
    }
}
</style>
